AppLinks

App Links

App Links 是一种特殊类型的 Deep Links,可以看作是 Deep Links 的升级版本(Android 6.0 引入)。二者主要区别在于:当用户点击 App Links 时将直接跳转到应用内容,而 Deep Links 则会弹出应用选择对话框(如果用户设备上有多个应用可以处理相同的 intent)。举例来说:在电子邮件中点击银行发送的 HTTP 网址,如果是 Deep Link 系统可能会显示一个对话框,询问用户是使用浏览器还是银行自己的应用打开此链接,而 App Link 则直接跳转到应用。

  1. Android App Links 在 Android6.0 及以上才能用
  2. 用 http/https 协议,包含 autoVerify 属性,该属性允许你把自己 APP 作为该 links 的默认处理者,点击链接就可以直达 APP,而不需要像 DeepLink 有个选择的弹窗来选择哪个应用来处理(解决 deeplink 二次模糊的弹窗)

若要添加对 Android App Links 的支持,请执行以下操作:

  1. manifest 文件中添加 intent-filters,需要添加 android:autoVerify="true",否则不会通过 host 的校验,app links 会不生效
  2. Launcher 的 Activity 添加处理到来的 Links
  3. 使用 Digital Asset Links 将应用与网站相关联,配置 assetlinks.json

添加 Intent Filters

  1. 依次选择 Tools > App Links Assistant
  2. 点击 Open URL Mapping Editor,然后点击 URL Mapping 列表底部的 Add
    aw0p8
  3. 以添加新的网址映射。

u8wiu

sv4zc

注意: path、 pathPrefix、 pathPattern 之间的区别

Intent-Filters 代码:

<activity
  android:name=".samples.basic.杂七杂八.链接打开App.urlscheme.URLSchemeActivity"
  android:exported="true"
  tools:ignore="AppLinkUrlError">

  <!-- for deep-link -->

  <!-- URI Scheme -->
  <intent-filter>
    <data
      android:host="hacket.me"
      android:scheme="hacket" />

    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
  </intent-filter>

  <!-- App Links -->
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="http" />
    <data android:host="hacket.me" />
  </intent-filter>
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="http" />
    <data android:host="hacket.me" />
  </intent-filter>
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="https" />
    <data android:host="hacket.me" />
  </intent-filter>
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="https" />
    <data android:host="hacket.me" />
  </intent-filter>
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="http" />
    <data android:host="lbo0d.test-app.link" />
  </intent-filter>
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="https" />
    <data android:host="lbo0d.test-app.link" />
  </intent-filter>
</activity>
<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data
        android:host="*.onelink.shein.com"
        android:scheme="https" />

</intent-filter>

Add logic to handle the intent 添加处理逻辑

f7wqt
添加如下代码:

class URLSchemeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        handleIntent(intent)
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleIntent(intent)
    }
    private fun handleIntent(intent: Intent) {
        val appLinkAction = intent.action
        val appLinkData: Uri? = intent.data
        if (Intent.ACTION_VIEW == appLinkAction) {
        	appLinkData?.lastPathSegment?.also { recipeId ->
            	Uri.parse("content://com.recipe_app/recipe/")
                    .buildUpon()
                    .appendPath(recipeId)
                    .build().also { appData ->
                        showRecipe(appData)
                }
        }
    }
}

添加 assetlinks.json 文件,声明你的网址和应用之间的关系
点击 App Links Assistant 中的 Open Digital Asset Links File Generator
gdr46

  1. 输入您的 Site domainApplication ID
  2. 如需在 Digital Asset Links 文件中添加对 一键登录 的支持,请选择 Support sharing credentials between the app and the website,输入网站的登录网址。此操作会将以下字符串添加到 Digital Asset Links 文件中,声明应用和网站共享登录凭据:delegate_permission/common.get_login_creds
  3. 指定 签名配置 或选择 密钥库文件
  4. 点击 Generate Digital Asset Links file
  5. Android Studio 生成文件后,点击 Save file 进行下载。
  6. assetlinks.json 文件上传到您的网站并允许所有人读取,网址为 https://yoursite/.well-known/assetlinks.jsonyoursite 就是你在 intent-filter 配置的 host。

系统会通过加密的 HTTPS 协议验证 Digital Asset Links 文件。请确保无论应用的 intent 过滤器是否包括 https,均可通过 HTTPS 连接访问 assetlinks.json 文件。

  1. 点击 Link and Verify 以确认您已将正确的 Digital Asset Links 文件上传到适当的位置

intent-filter 配置

intent-filter 错误配置

同一个 intent filter 内所有的 <data> 元素会合并在一起,以解释他们所有组合属性的变量。

错误案例: 要配置 app.xxx.xxxapi-.xxx.xxx.com/h5/sharejump/appjump 两种域名的 Applinks 错误配置

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data
        android:host="app.xxx.com"
        android:scheme="https"/>
    <data
        android:host="app.xxx.tw"
        android:scheme="https"/>
    <data
        android:host="app.xxx.se"
        android:scheme="https"/>
  	<data
        android:host="api-xxx.xxx.com"
        android:pathPrefix="/h5/sharejump/appjump"
        android:scheme="https" />
    <data
        android:host="api-xxx.xxx.com"
        android:pathPrefix="/h5/sharejump/appjump"
        android:scheme="http" />
</intent-filter>

同一个 intent-filter 中,hostschemepathpathPrefixpathPattern 如果配置了多个,他们之间会互相组合的,就会导致原本的 https://app.xxx.tw 这种 Applinks 失效,必须加上 pathPrefix 才行:https://app.xxx.tw//h5/sharejump/appjump

解决: app.xxx.xxx 和 api-.xxx.xxx.com/h5/sharejump/appjump 要分开在不同的 intent-filter 中配置

<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data
    android:host="app.xxx.com"
    android:scheme="https"/>
  <data
    android:host="app.xxx.tw"
    android:scheme="https"/>
  <data
    android:host="app.xxx.se"
    android:scheme="https"/>
</intent-filter>
<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="https"/>
    <data android:host="api-shein.shein.com"/>
    <data android:pathPrefix="/h5/sharejump/appjump"/>
    <data android:scheme="http"/>
    <data android:host="api-shein.shein.com"/>
    <data android:pathPrefix="/h5/sharejump/appjump"/>
</intent-filter>

支持不同的子域名

数字资产链接协议把你 intent filter 里的子域名看做唯一的、独立的域名。因此,如果你的 intent filter 列出一个域名及其多个子域名,你需要在每个子域名上发布一个有效的 assetlinks.json 文件。

例如:下面的 intent filter 包含了<www.example.com>和 mobile.example.com 作为期望处理的 intent 的 URL 的主机名。因此,有效的 assetlinks.json 必须同时发布在https://www.example.com/.well-known/assetlinks.jsonhttps://mobile.example.com/.well-known/assetlinks.json。>

<application>
  <activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" android:host="www.example.com" />
      <data android:scheme="https" android:host="mobile.example.com" />
    </intent-filter>
  </activity>
</application>

或者,如果你用通配符定义了你要处理的主机名 (如 *.example.com),那么你需要把你的 assetlinks.json 文件发布在根主机名 (根域名) 下 (example.com)。

比如,一个以定义了如下 intent filter 的应用,如果 assetlinks.json 发布在https://example.com/.well- known/assetlinks.json,它的任一子域名 (如 foo.example.com) 将会通过验证。

<application>
  <activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" android:host="*.example.com" />
    </intent-filter>
  </activity>
</application>

配置路径:https://yoursite/.well-known/assetlinks.json

单一网站和单一应用之间的关系

数字资产证明文件必须发布在你的网站上,以证明你的应用是和网站关联在一起的,并且用于验证应用内的 URL 链接模式。这个 JSON 文件用下面几个字段来标识关联的应用:

这个字段支持多个指纹信息,可以用来支持不同的应用版本,如开发版本和发布版本

下面这个示例 assetlinks.json 授予链接打开权限给 com.example 应用

[{  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

让同一网站和不同应用关联起来

网站可以在同一个 assetlinks.json 文件里声明和不同的 app 的关系。下面这个文件列出了两个声明,这两个声明声明了网站和两个应用之间的关联,这个文件位于https://www.example.com/.well-known/assetlinks.json:>

[{  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.puppies.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
},
  {
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.monkeys.app",
      "sha256_cert_fingerprints":
      ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
    }
  }]

不同应用或许会处理同一个域名下的不同资源链接。比如:app1 声明一个 intent filter 用于处理https://example.com/articles,app2 声明一个 intent> filter 用于处理https://example.com/videos。>

注意:关联同一个域名的不同应用可能会使用相同或不同的签名文件。

关联一个应用到不同网站

不同的网站可以在它们的 assetlinks.json 文件里声明关联同一个应用。

[{  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]
[{  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

发布 JSON 验证文件

Android applinks assetlinks.json配置指南

验证 Android 应用链接  |  Android 开发者  |  Android Developers

你的 app links 的 intent-filter 配置:

<activity ...>
  <intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="http" android:host="www.example.com" />
    <data android:scheme="https" />
  </intent-filter>
</activity>

android:autoVerify="true" 出现在你任意一个 intent filter 里,在 Android 6.0 及以上的系统上安装应用的时候,会触发系统对 APP 里和 URL 有关的每一个域名的验证。验证过程设计以下步骤:

  1. 系统会检查所有包含以下特征的 intent filter:Action 为 android.intent.action.VIEW、Category 为 android.intent.category.BROWSABLEandroid.intent.category.DEFAULT、Data scheme 为 http或https
  2. 对于在上述 intent filter 里找到的每一个唯一的域名,Android 系统会到对应的域名下查找数字资产文件,地址是:https://域名/.well-known/assetlinks.json

只有当系统为 AndroidManifest 里找到的每一个域名找到对应的数字资产文件,系统才会把你的应用设置为特定链接的默认处理器
在你安装 APP 后,会请求这个来验证,抓包看
7j5xw

方式一:请求 googleapis 来验证

https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://yourhost&relation=delegate_permission/common.handle_all_urls>

如:https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://app.shein.com&relation=delegate_permission/common.handle_all_urls>
出现类似:
7zfpf

Test statement

当实现 APP Links 特性时,你需要测试链接功能是否可用,以保证系统能够将你的 APP 和网站关联起来,并如预期地处理 URL 请求。

uhjd4
说明:

Generate statement

Generate statement:帮我们生成 assetlinks.json 文件

Test statement: 测试是否配置成功
k9jib

我们可以按 F12 打开开发者工具,来查看具体的错误信息:
lv9rh

如:https://app.shein.tw/.well-known/assetlinks.json
但有的是在浏览器中访问不了的,这种就可以用前面的方式来验证
https://app.shein.com/.well-known/assetlinks.json

如何出现这种,就是运维把证书配置错了:

hg4k3

方式四:安装到设备看 log

将应用安装到设备上,等待 20 秒左右,进行验证

在应用安装后,等待至少 20 秒的时间,以便系统验证完毕。但是,上文只告诉我们如何获得应用是否是特定域名的默认处理器的配置信息,系统的这个验证过程是否发起,是否执行完毕,验证结果如何,我们是无从得知的。

验证成功会有类似日志信息:

2020-09-27 11:57:48.216 10414-27720/? I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:32 scheme:"https" hosts:"mashi-alternate.test-app.link mashi.test-app.link" package:"club.jinmei.mgvoice". [CONTEXT service_id=244 ]
2020-09-27 11:58:20.534 10414-27720/? I/IntentFilterIntentOp: Verification 32 complete. Success:false. Failed hosts:mashi-alternate.test-app.link,mashi.test-app.link. [CONTEXT service_id=244 ]

这种方式不一样好使

方式五:获取设备上所有应用的链接处理策略命令

输出当前手机所有 app links 的包名

adb shell dumpsys package domain-preferred-apps

4h9u8
后面跟 verified 说明验证通过了。

adb shell dumpsys package d

0shny

方式六:Android12 及以上命令验证 (推荐)

从 Android12 开始,可以手动调用 app links 域名验证,不管你的 APP 的 targetSdkVersion 是否是 Android12 了。

  1. 设置支持 app links 域名校验
    • 如果你的应用的 targetSdkVersion 已经是 Android12,那么自动开启验证
    • 如果你的应用的 targetSdkVersion 小于 Android12,需要手动开启:adb shell am compat enable 175408749 PACKAGE_NAME
  2. 重置设备上 App Links 的状态

adb shell pm set-app-links --package PACKAGE_NAME 0 all
如:
adb shell pm set-app-links --package com.zzkko 0 all

  1. 调用 app links 域名校验

adb shell pm verify-app-links --re-verify PACKAGE_NAME
如:adb shell pm verify-app-links --re-verify com.zzkko

  1. 查看校验结果

adb shell pm get-app-links PACKAGE_NAME
如:adb shell pm get-app-links com.zzkko

2up7z

用浏览器/备忘录/Pushbullet 测试

浏览器:

备忘录:

如果未验证成功或者集成不对,还是弹窗来选择了
s9ucg
Pushbullet

adb+URL Intent 测试

adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE \
    -d "http://你的域名:可选的端口"
# 如
adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://app.shein.com"

在 Android 手机上的 Chrome 浏览器、猎豹浏览器、UC 浏览器里直接输入网址来验证,均无法触发系统的 AppLinks 特性。推测浏览器内发起的跳转,会被浏览器直接拦截处理了,因此无法进入系统的分发处理 Intent 流程,故没触发 AppLinks 特性。

对 ink 域名不太友善

在测试中发现,国内各大厂商对 .ink 域名不太友善,很多的是被支持了 .com 域名,但是不支持 .ink 域名。

机型 版本 是否识别 ink 是否识别 com
小米 MI6 Android 8.0 MIUI 9.5
小米 MI5 Android 7.0 MIUI 9.5
魅族 PRO 7 Android 7.0 Flyme 6.1.3.1A
三星 S8 Android 7.0 是,弹框
华为 HonorV10 Android 8.0 EMUI 8.0
oppo R11s Android 7.1.1 ColorOS 3.2
oppo A59s Android 5.1 ColorOS 3.0 是,不能跳转到 app 是,不能跳转到 app
vivo X6Plus A Android 5.0.2 Funtouch OS_2.5
vivo 767 Android 6.0 Funtouch OS_2.6 是,不能跳转到 app 是,不能跳转到 app
vivo X9 Android 7.1.1 Funtouch OS_3.1 是,不能跳转到 app 是,不能跳转到 app

数据来源网络,未验证真实

1、检查 intent-filter 是否配置对了?

  1. 直接访问看是否正常,如 assetlinks.json
  2. Statement List Generator and Tester 工具(需要包名、证书和域名)
  3. 直接访问 GoogleApi,如 digitalassetlinks.googleapis.com/ 传入自己的包名(app 首次安装时会访问该接口去校验)

3、查看 APP 是否校验成功(APP 首次安装会去校验)

  1. ADB 命令校验:adb shell pm get-app-links com.zzkko,出现 verified 就是校验成功,1024 或 none 就是未成功
  2. 如果未校验成功,1024 一般是代理问题,看安装包是是否开启了抓包工具的代理,需要关闭代理,如 Charles
  3. 要校验成功需要科学上网

4、直接注入 url 和点击 url 跳转

如果是直接输入 URL 访问,也是拉不起 APP 的

浏览器中 " 输入 URL 访问 " 和 " 点击链接访问 " 的区别

这两种互动方式的主要区别在于用户行为的触发方式,也会影响 applinks 的处理逻辑。具体如下:

1. 输入 URL 访问
2. 点击链接访问

具体行为上的技术区别

行为触发方式 请求对象 是否直接跳转到 App
手动输入 URL 访问 直接发送 HTTP/HTTPS 请求,访问网页为主 通常不会直接跳转到 App,系统默认优先网页加载。
点击链接访问 浏览器会递交该 URL,由 OS 或目标 App 进行处理 如果支持 Universal Links 或 App Links,支持直接跳转到 App。

这两者的技术差异归因于以下几个关键因素:

1. 操作系统对链接的处理优先级
2. 浏览器的处理逻辑

不同的浏览器对直接输入 URL 和点击链接的处理方式也可能不同:

class CustomWebViewActivity : AppCompatActivity() {

    private lateinit var webView: WebView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 初始化 WebView
        webView = findViewById(R.id.webView)
        webView.settings.javaScriptEnabled = true // 启用 JavaScript
        webView.settings.domStorageEnabled = true // 启用 DOM 存储

        // 自定义 WebViewClient
        webView.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
                val url = request.url.toString()

                // 检查是否是 App Links
                if (isAppLink(url)) {
                    // 跳转到相关 App
                    openAppLinkIntent(url)
                    return true // 已处理,不再加载 URL
                }

                // 默认行为:继续加载 URL
                return false
            }
        }

        // 加载初始网页
        webView.loadUrl("https://example.com")
    }

    /**
     * 判断 URL 是否为 App Links(匹配规则可以定制)
     */
    private fun isAppLink(url: String): Boolean {
        return url.contains("example.com/deeplink") // 检查链接是否符合 App Links 定义规则
    }

    /**
     * 使用 Intent 打开 App Links
     */
    private fun openAppLinkIntent(url: String) {
        try {
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            startActivity(intent) // 调用目标 App
        } catch (e: Exception) {
            e.printStackTrace()
            // 处理未安装目标 App 的情况(例如引导用户下载)
        }
    }
}

应用安装的时候根据 activity 标签中的 data 的内容到这个网页下面去获取对应域名下的 assetlinks.json 进行校验,如果符合条件则把 这个 url 保存在本地,当点击 webview 或者短信里面的 url 的时候,系统会自动与本地库中的域名相匹配, 如果匹配失败则会被自动认为是 deeplink 的连接。

  1. Deep Links 是一种允许用户进入应用某个特定 Activity 的 intent filter。点击这类链接时,系统可能会弹出一个选择列表,让用户在一堆能够处理这类链接的应用里 (包括你的) 选择一个来处理该链接。

例如:用户点击了一个地图相关的链接,系统弹出一个选择列表,让用户选择是要使用地图应用来处理,还是使用 Chrome 浏览器来处理。

  1. App Links 是一种基于你的网站地址且验证通过的 Deep Links。因此,点击一个这样的链接会直接打开你的应用 (如果已经安装),系统将不会弹出选择列表。当然,后续用户可以更改配好设置,来指定由哪个应用程序处理这类链接。

下面这个列表描述更多差异:


Deep Links App Links
Intent URL Scheme https, http,或者自定义 需为 http 或 https
Intent Action 任意 Action 需为 android.intent.action.VIEW
Intent Category 任意 Category 需为 android.intent.category.BROWSABLEandroid.intent.category.DEFAULT
链接验证 不需要 需要在网站上放置一个数字资产链接,并能够通过 HTTPS 访问
用户体验 可能会弹出一个选择列表给用户选择用哪个应用处理连接 没有弹框,系统直接打开你的应用处理网站连接
兼容性 所有 Android 版本 Android 6.0 及以上

Universal Link 是 Apple 在 iOS 9 推出的一种能够方便的通过传统 HTTPS 链接来启动 APP 的功能。可以无缝重定向到对应的 APP,且不需要通过 Safari 浏览器。如果你的应用不支持的话,则会在 Safari 中打开该链接。